#ifndef MODULAR_REDUCTION_H
#define MODULAR_REDUCTION_H
#include <cstdint>
#include <vector>
#include "utils.h"


std::vector<uint64_t> BRedParams(uint64_t q);
uint64_t BRedAdd(uint64_t a, uint64_t q, const std::vector<uint64_t> &u);
uint64_t BRed(uint64_t x, uint64_t y, uint64_t q, const std::vector<uint64_t> &u);
uint64_t CRed(uint64_t a, uint64_t q);
void Mul64(uint64_t x, uint64_t y, uint64_t &mhi, uint64_t &mlo);
void Add64(uint64_t x, uint64_t y, uint64_t carry, uint64_t &sum, uint64_t &carryOut);

void MulScalarBarrettVec(std::vector<uint64_t> &p1, std::vector<uint64_t> &p2, uint64_t scalarMont, uint64_t qi,
    uint64_t len);
void MulCoeffsBarrettConstantVec(std::vector<uint64_t> &p1, std::vector<uint64_t> &p2, std::vector<uint64_t> &p3,
    uint64_t qi, uint64_t len);
void MulCoeffsBarrettConstantAndAddNoModVec(std::vector<uint64_t> &p1, std::vector<uint64_t> &p2,
    std::vector<uint64_t> &p3, uint64_t qi, uint64_t len);

#endif // MODULAR_REDUCTION_H